import java.util.Collections;
import java.util.Vector;

import org.joda.time.DateTime;
import org.joda.time.LocalDate;

//@author A0099943J
public class TaskList {
	private static final int NO_MATCH_FOUND = -1;

	private Vector<Task> list;

	//@author A0099943J
	public TaskList() {
		list = new Vector<Task>();
	}

	//@author A0099943J
	public TaskList(Vector<Task> _list) {
		list = _list;
	}

	//@author A0099943J
	public Task getTask(int index) throws IndexOutOfBoundsException {
		return list.get(index);
	}

	//@author A0099943J
	public int getNumTask() {
		return list.size();
	}

	//@author A0099943J

	public Vector<Task> toVector() {
		return list;
	}

	//@author A0099943J
	public Task setTask(int taskIndex, String taskDescription, DateTime taskStartDateTime, DateTime taskEndDateTime) {
		Task temp = getTask(taskIndex);
		temp.setDescription(taskDescription);
		temp.setStartDateTime(taskStartDateTime);
		temp.setEndDateTime(taskEndDateTime);
		list.set(taskIndex,temp);
		Collections.sort(list);
		return temp;
	}

	//@author A0099943J
	public void setTask(int taskIndex, String taskDescription) {
		Task temp = getTask(taskIndex);
		temp.setDescription(taskDescription);
		list.set(taskIndex,temp);
		Collections.sort(list);
	}

	//@author A0099943J
	public Vector<Integer> getExpiredTasks() {
		Vector<Integer> expiredTasks = new Vector<Integer>();

		for (int i=0; i < getNumTask(); i++) {
			Task currentTask = getTask(i);
			if (currentTask.getEndDateTime().isBeforeNow()) {
				expiredTasks.add(i);
			}
		}

		return expiredTasks;
	}

	//@author A0099943J
	public Vector<Integer> getTodayTask() {
		LocalDate today = DateTime.now().toLocalDate();
		return getTaskOfDate(today);
	}

	//@author A0099943J
	public Vector<Integer> getTaskOfDate(LocalDate date) {
		Vector<Integer> taskIndex = new Vector<Integer> ();

		for (int i=0; i < getNumTask(); i++) {
			Task currentTask = getTask(i);
			if (currentTask.containsDate(date)) {
				taskIndex.add(i);
			}
		}     

		return taskIndex;
	}

	//@author A0099943J
	public Vector<Integer> getTaskOfDateTime(DateTime dateTime) {
		Vector<Integer> taskIndex = new Vector<Integer>();

		for (int i=0; i < getNumTask(); i++) {
			Task currentTask = getTask(i);
			if  (currentTask.contains(dateTime)) {
				taskIndex.add(i);
			}
		}

		return taskIndex;
	}

	//@author A0099943J
	public Vector<Integer> searchTaskByKeywords(Vector <String> keywords) {
		Vector <Integer> taskIndex = new Vector<Integer>();

		for (int i=0; i < getNumTask(); i++) {
			String currentTaskDescription = getTask(i).getDescription();
			// Normalize by adding space at beginning and end
			currentTaskDescription = " ".concat(currentTaskDescription).concat(" ");
			boolean containAllKeywords = true;
			for (int j=0; j < keywords.size(); j++) {
				if (!currentTaskDescription.contains(keywords.get(j))) {
					containAllKeywords = false;
					break;
				}
			}
			if (containAllKeywords) {
				taskIndex.add(i);
			}
		}

		return taskIndex;
	}

	//@author A0099943J
	public Vector<Integer> getCompleteTask() {
		return getTaskOfStatus(true);
	}

	//@author A0099943J
	public Vector<Integer> getIncompleteTask() {
		return getTaskOfStatus(false);
	}

	//@author A0099943J
	private Vector<Integer> getTaskOfStatus(boolean status) {
		Vector<Integer> statusTask = new Vector<Integer> ();

		for (int i=0; i < getNumTask(); i++) {
			Task currentTask = getTask(i);
			if (currentTask.getStatus() == status) {
				statusTask.add(i);
			}
		}

		return statusTask;
	}

	//@author A0099943J
	public int searchTask (Task task) {
		for (int i=0; i < list.size(); i++) {
			if (list.get(i).isEqual(task))
				return i;
		}
		return NO_MATCH_FOUND;
	}

	//@author A0099943J
	public void addTask(Task newTask) {
		list.add(newTask);
		Collections.sort(list);
	}

	//@author A0099943J
	public void deleteTask(int taskIndex) {
		list.remove(taskIndex);
	}

	//@author A0099943J
	public void setTaskStatus(int taskIndex, boolean status) {
		Task temp = getTask(taskIndex);
		temp.setStatus(status);
		list.set(taskIndex,temp);
	}

	//@author A0099943J
	public boolean isEmpty() {
		return list.isEmpty();
	}

	//@author A0099943J
	public int getNumTasks() {
		return list.size();
	}

}